package com.example.his.api.controller;


import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.json.JSONUtil;
import com.example.his.api.common.PageUtils;
import com.example.his.api.common.R;
import com.example.his.api.controller.form.*;
import com.example.his.api.db.pojo.UserEntity;
import com.example.his.api.mis.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping ( "/mis/user" )
public class UserController {

  // 引入service
  @Resource
  private UserService userServeice;
  @Autowired
  private UserService userService;

  /**
   * 用户登录接口
   * 接收登录表单数据，验证后转换为Map传递给业务层处理
   * 登录成功返回令牌和权限列表，失败返回错误结果
   */
  @PostMapping ( "/login" )
  public R login( @RequestBody @Valid LoginForm form ) {
    // 将登录表单数据转换为Map，用于传递给业务层
    Map param = BeanUtil.beanToMap( form );

    // 调用UserService进行登录验证，获取用户ID
    Integer userId = userServeice.login( param );
    // 如果用户ID不为空，表示登录成功
    if ( userId != null ) {
      // 登出可能存在的旧会话
      StpUtil.logout( userId, "Web" );

      // 登录新会话
      StpUtil.login( userId, "Web" );

      // 生成新的令牌
      String token = StpUtil.getTokenValueByLoginId( userId, "Web" );

      // 获取权限列表
      List < String > permissions = StpUtil.getPermissionList();

      // 返回登录成功信息和权限数据
      return R.ok()
          .put( "result", true )
          .put( "token", token )
          .put( "permission", permissions );
    }

    // 登录失败，返回错误结果
    return R.ok().put( "result", false );
  }

  /**
   * 用户退出登录接口
   * 需要用户已登录才能操作
   * 获取当前登录的用户ID，执行登出操作
   * 返回登出成功的提示信息
   */
  @GetMapping ( "/logout" )
  @SaCheckLogin
  public R logout() {
    // 获取当前登录用户ID
    int userId = StpUtil.getLoginIdAsInt();

    // 登出当前会话
    StpUtil.logout( userId, "Web" );

    // 返回登出成功响应
    return R.ok().put( "msg", "退出登录成功" );
  }

  /**
   * 更新用户密码接口
   * 需要用户已登录才能操作
   * 接收更新密码表单数据，包含原密码和新密码
   * 通过SaToken获取当前登录用户ID，构建参数Map传递给业务层处理
   * 返回受影响的行数
   */
  @PostMapping ( "/updatePassword" )
  @SaCheckLogin
  public R updatePassword( @RequestBody @Valid UpdatePasswordForm form ) {
    // 获取当前登录用户ID
    int userId = StpUtil.getLoginIdAsInt();

    // 构建参数Map，包含用户ID、原密码和新密码
    HashMap param = new HashMap <>() {{
      put( "userId", userId );
      put( "password", form.getPassword() );
      put( "newPassword", form.getNewPassword() );
    }};

    // 调用UserService更新密码
    int rows = userService.updatePassword( param );

    // 返回操作结果
    return R.ok().put( "rows", rows );
  }

  /**
   * 分页查询用户信息
   * 需要ROOT权限或USER:SEARCH权限才能访问
   * 接收分页查询表单参数，转换为Map后添加分页起始位置参数
   * 调用UserService执行分页查询，并将结果封装为PageUtils返回
   */
  @PostMapping ( "/searchByPage" )
  @SaCheckPermission ( value = { "ROOT", "USER:SELECT" }, mode = SaMode.OR )
  public R searchByPage( @Valid @RequestBody SearchUserByPageForm form ) {
    int page = form.getPage();
    int length = form.getLength();
    int start = ( page - 1 ) * length;
    Map param = BeanUtil.beanToMap( form );
    param.put( "start", start );
    PageUtils pageUtils = userService.searchByPage( param );
    return R.ok().put( "page", pageUtils );
  }


  /**
   * 新增用户接口
   * 需要ROOT权限或USER:INSERT权限才能访问
   * 接收用户新增表单数据，转换为UserEntity对象后设置默认状态和角色信息
   * 调用UserService执行新增操作，返回受影响的行数
   */
  @PostMapping ( "/insert" )
  @SaCheckPermission ( value = { "ROOT", "USER:INSERT" }, mode = SaMode.OR )
  public R insert( @RequestBody @Valid InsertUserForm form ) {
    // 将表单数据转换为UserEntity对象
    UserEntity user = BeanUtil.toBean( form, UserEntity.class );
    // 设置用户状态为正常（1）
    user.setStatus( 1 );
    // 将角色数组转换为JSON字符串存储
    user.setRole( JSONUtil.parseArray( form.getRole() ).toString() );
    // 调用UserService执行新增操作
    int rows = userService.insert( user );
    // 返回操作结果
    return R.ok().put( "rows", rows );
  }

  /**
   * 根据用户ID查询用户信息接口
   * 需要ROOT权限或USER:UPDATE权限才能访问
   * 接收包含用户ID的表单数据，调用UserService根据ID查询用户信息
   * 返回查询到的用户信息Map
   */
  @PostMapping ( "/searchById" )
  @SaCheckPermission ( value = { "ROOT", "USER:UPDATE" }, mode = SaMode.OR )
  public R searchById( @RequestBody @Valid SearchUserByIdForm form ) {
    // 调用UserService根据用户ID查询用户信息
    HashMap map = userService.searchById( form.getUserId() );
    // 打印userID
    System.out.println( "userID: " + form.getUserId() );
    // 返回查询结果
    return R.ok().put( "map", map );
  }

  /**
   * 更新用户信息接口
   * 需要ROOT权限或USER:UPDATE权限才能访问
   * 接收用户更新表单数据，将表单数据转换为Map，并将角色数组转换为JSON字符串
   * 调用UserService执行更新操作
   * 如果更新成功，则强制用户重新登录（登出当前会话）
   * 返回受影响的行数
   */
  @PostMapping ( "/update" )
  @SaCheckPermission ( value = { "ROOT", "USER:UPDATE" }, mode = SaMode.OR )
  public R update( @RequestBody @Valid UpdateUserForm form ) {
    // 将表单数据转换为Map
    Map param = BeanUtil.beanToMap( form );

    // 将角色数组转换为JSON字符串并替换Map中的role字段
    param.replace( "role", JSONUtil.parseArray( form.getRole() ).toString() );

    // 调用UserService执行更新操作
    int rows = userService.update( param );

    // 如果更新成功（影响行数为1），则登出该用户的当前会话
    if ( rows == 1 ) {
      StpUtil.logout( form.getUserId(), "Web" );
    }

    // 返回操作结果
    return R.ok().put( "rows", rows );

  }

  /**
   * 批量删除用户接口
   * 需要ROOT权限或USER:DELETE权限才能访问
   * 接收包含用户ID数组的表单数据，执行批量删除操作
   * 删除前会检查是否包含当前登录用户，避免自我删除
   * 删除成功后会登出被删除用户的会话
   * 返回受影响的行数
   */
  @PostMapping ( "/deleteByIds" )
  @SaCheckPermission ( value = { "ROOT", "USER:DELETE" }, mode = SaMode.OR )
  public R deleteByIds( @Valid @RequestBody DeleteUserByIdsForm form ) {
    Integer userId = StpUtil.getLoginIdAsInt();
    if ( ArrayUtil.contains( form.getIds(), userId ) ) {
      return R.error( "您不能删除自己的帐户" );
    }
    int rows = userService.deleteByIds( form.getIds() );
    if ( rows > 0 ) {
      for ( Integer id : form.getIds() ) {
        StpUtil.logout( id );
      }
    }
    return R.ok().put( "rows", rows );
  }

  /**
   * 人员离职接口
   * 需要ROOT权限或USER:DELETE权限才能访问
   * 接收包含用户ID的表单数据，调用UserService执行人员离职操作
   * 离职成功后会登出该用户的会话
   * 返回受影响的行数
   */
  @PostMapping ( "/dismiss" )
  @SaCheckPermission ( value = { "ROOT", "USER:DELETE" }, mode = SaMode.OR )
  public R dismiss( @RequestBody @Valid DismissForm form ) {
    // 调用UserService执行人员离职操作
    int rows = userService.dismiss( form.getUserId() );
    
    // 如果离职成功，则登出该用户的会话
    if ( rows > 0 ) {
      StpUtil.logout( form.getUserId().intValue() );
    }
    
    // 返回操作结果
    return R.ok().put( "rows", rows );
  }

}
